//
//  UIView+Ext.swift
//  CocoProject
//
//  Created by Vill on 2023/11/3.
//

import Foundation

private var TapHanlderKey: Void?
private var TapGestureKey: Void?

// MARK: - 方法
public extension UIView {
    
    var size: CGSize {
        get { return frame.size }
        set { width = newValue.width; height = newValue.height }
    }
    
    var width: CGFloat {
        get { return frame.size.width }
        set { return frame.size.width = newValue }
    }
    
    var height: CGFloat {
        get { return frame.size.height }
        set { return frame.size.height = newValue }
    }
    
    var x: CGFloat {
        get { return frame.origin.x }
        set { frame.origin.x = newValue }
    }
    
    var y: CGFloat {
        get { return frame.origin.y }
        set { frame.origin.y = newValue }
    }
    
    var left: CGFloat {
        get { return x }
        set { x = newValue }
    }
    
    var top: CGFloat {
        get { return y }
        set { y = newValue }
    }
    
    var right: CGFloat {
        get { return x + width }
        set { x = newValue - width }
    }
    
    var bottom: CGFloat {
        get { return y + height }
        set { y = newValue - height }
    }
    
    var centerX: CGFloat {
        get { return center.x }
        set { center.x = newValue }
    }
    
    var centerY: CGFloat {
        get { return center.y }
        set { center.y = newValue }
    }
    
    var origin: CGPoint {
        get { return frame.origin }
        set { frame.origin = newValue }
    }
    
    func set(left:CGFloat){
        let frame = self.frame
        self.frame = CGRect(x: left, y: frame.origin.y, width: frame.size.width, height: frame.size.height)
    }
    
    func set(top:CGFloat){
        let frame = self.frame
        self.frame = CGRect(x: frame.origin.x, y: top, width: frame.size.width, height: frame.size.height)
    }
    
    func removeAllSuberviews(){
        subviews.forEach{ $0.removeFromSuperview() }
    }
    
    //MARK: -- 添加圆角
    func clipsCorners(corners: UIRectCorner, radius: CGFloat) {
        let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = maskPath.cgPath
        self.layer.mask = maskLayer
    }
    
    func clipsAllCorners(radius: CGFloat) {
        self.clipsCorners(corners: [.topLeft, .topRight, .bottomLeft, .bottomRight], radius: radius)
    }
    
    //MARK: -- layer设置圆角
    func setBorderCorners(color: UIColor = .clear,borderWidth:CGFloat = 1, radius: CGFloat) {
        self.layer.borderColor = color.cgColor
        self.layer.borderWidth = borderWidth
        self.layer.cornerRadius = radius
        self.layer.masksToBounds = true
    }
    
    //MARK: -- 添加点击事件
    func addTap(tapHanlder: @escaping (UITapGestureRecognizer) -> Void) {
        self.isUserInteractionEnabled = true
        var tap = objc_getAssociatedObject(self, &TapGestureKey) as? UITapGestureRecognizer
        if tap == nil {
            tap = UITapGestureRecognizer(target: self, action: #selector(tapA(tap:)))
            self.addGestureRecognizer(tap!)
            objc_setAssociatedObject(self, &TapGestureKey, tap, .OBJC_ASSOCIATION_RETAIN);
        }
        objc_setAssociatedObject(self, &TapHanlderKey, tapHanlder, .OBJC_ASSOCIATION_COPY)
    }
    
    @objc private func tapA(tap: UITapGestureRecognizer) {
        if tap.state == .recognized {
            if let hanlder = objc_getAssociatedObject(self, &TapHanlderKey) as? (UITapGestureRecognizer) -> Void {
                hanlder(tap)
            }
        }
    }
    
    /// 返回视图的控制器对象
    ///
    /// - Returns: 控制器对象，可能为空
    func viewController() -> UIViewController? {
        var view: UIView? = self
        repeat {
            if let nextResponder = view?.next {
                if nextResponder.isKind(of: UIViewController.self) {
                    return nextResponder as? UIViewController
                }
            }
            view = view?.superview
        } while view != nil
        
        return nil
    }
    
    //MARK: -- 渐变背景 垂直方向 way是否插在涂层下边
    func setGradientBgColor(colors: [UIColor], locations:[NSNumber] = [0.0, 1.0], way:Bool = false) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame =  CGRect(origin: .zero, size: self.bounds.size)
        gradientLayer.startPoint = CGPoint(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint(x: 0, y: 1)
        gradientLayer.colors = colors.map({$0.cgColor})
        gradientLayer.locations = locations
        if way == true{
            self.layer.insertSublayer(gradientLayer, at: 0)
        }else{
            self.layer.addSublayer(gradientLayer)
        }
    }
    
    //MARK: -- 边框
    func addGradientBorder(colors: [UIColor], startPoint: CGPoint = CGPoint(x: 0, y: 0.5), endPoint: CGPoint = CGPoint(x: 1, y: 0.5),lineWidth:CGFloat = 1, cornerRadius: CGFloat) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colors.map { $0.cgColor }
        gradientLayer.locations = [0.0, 0.5, 1.0]
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        gradientLayer.frame = self.bounds
        
        let maskPath = UIBezierPath(roundedRect: CGRect(x: lineWidth / 2, y: lineWidth / 2, width: bounds.width - lineWidth, height: bounds.height - lineWidth), cornerRadius: cornerRadius)
        let maskLayer = CAShapeLayer()
        maskLayer.path = maskPath.cgPath
        maskLayer.fillColor = UIColor.clear.cgColor
        maskLayer.strokeColor = UIColor.black.cgColor
        maskLayer.lineWidth = lineWidth
        gradientLayer.mask = maskLayer
        layer.addSublayer(gradientLayer)
    }
}

extension UIApplication {
    func getKeyWindow() -> UIWindow? {
        if #available(iOS 15, *) {
            return self.windows.first(where: { $0.isKeyWindow })
        } else if #available(iOS 13, *) {
            return self.connectedScenes
                .filter({ $0.activationState == .foregroundActive })
                .compactMap({ $0 as? UIWindowScene })
                .first?
                .windows
                .first(where: { $0.isKeyWindow })
        } else {
            return self.keyWindow
        }
    }
}
